#!/usr/bin/env node

/**
 * 生成安全密钥工具
 * 用于生成JWT_SECRET、REFRESH_TOKEN_SECRET和ENCRYPTION_KEY
 */

const crypto = require('crypto');
const fs = require('fs');
const path = require('path');

console.log('🔐 2FA Manager - 安全密钥生成工具\n');

// 生成密钥
const jwtSecret = crypto.randomBytes(32).toString('base64');
const refreshTokenSecret = crypto.randomBytes(32).toString('base64');
const encryptionKey = crypto.randomBytes(32).toString('hex');

console.log('✅ 已生成以下安全密钥：\n');

console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('JWT_SECRET（JWT访问令牌密钥）:');
console.log(jwtSecret);
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');

console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('REFRESH_TOKEN_SECRET（刷新令牌密钥）:');
console.log(refreshTokenSecret);
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');

console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
console.log('ENCRYPTION_KEY（AES-256加密密钥）:');
console.log(encryptionKey);
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');

// 询问是否自动创建.env文件
const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.question('\n是否自动创建/更新后端.env文件？(y/n): ', (answer) => {
  if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
    createEnvFile(jwtSecret, refreshTokenSecret, encryptionKey);
  } else {
    console.log('\n✋ 已取消自动创建。请手动将上述密钥复制到 backend/.env 文件中。');
    showInstructions();
  }
  rl.close();
});

function createEnvFile(jwt, refresh, encryption) {
  const backendEnvPath = path.join(__dirname, '../backend/.env');
  const backendEnvExamplePath = path.join(__dirname, '../backend/.env.example');
  
  try {
    let envContent;
    
    // 如果存在.env.example，使用它作为模板
    if (fs.existsSync(backendEnvExamplePath)) {
      envContent = fs.readFileSync(backendEnvExamplePath, 'utf8');
    } else {
      // 否则创建基本配置
      envContent = `# 2FA Manager Backend Environment Variables
NODE_ENV=development
PORT=5000
HOST=localhost
DATABASE_URL=file:./dev.db

JWT_SECRET=placeholder
REFRESH_TOKEN_SECRET=placeholder
ENCRYPTION_KEY=placeholder

JWT_EXPIRES_IN=15m
REFRESH_TOKEN_EXPIRES_IN=7d

ALLOWED_ORIGINS=http://localhost:3000
LOG_LEVEL=debug

COOKIE_SECURE=false
COOKIE_SAME_SITE=strict
`;
    }
    
    // 替换密钥
    envContent = envContent.replace(
      /JWT_SECRET=.*/,
      `JWT_SECRET=${jwt}`
    );
    envContent = envContent.replace(
      /REFRESH_TOKEN_SECRET=.*/,
      `REFRESH_TOKEN_SECRET=${refresh}`
    );
    envContent = envContent.replace(
      /ENCRYPTION_KEY=.*/,
      `ENCRYPTION_KEY=${encryption}`
    );
    
    // 写入文件
    fs.writeFileSync(backendEnvPath, envContent);
    
    console.log('\n✅ 成功创建 backend/.env 文件！');
    console.log('📁 文件路径:', backendEnvPath);
    
    // 设置文件权限（仅Unix系统）
    if (process.platform !== 'win32') {
      try {
        fs.chmodSync(backendEnvPath, 0o600);
        console.log('🔒 已设置文件权限为 600（仅所有者可读写）');
      } catch (e) {
        console.log('⚠️  无法设置文件权限，请手动执行: chmod 600 backend/.env');
      }
    }
    
    showInstructions();
    
  } catch (error) {
    console.error('\n❌ 创建.env文件失败:', error.message);
    console.log('\n请手动创建 backend/.env 文件，并复制上述密钥。');
    showInstructions();
  }
}

function showInstructions() {
  console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
  console.log('📝 后续步骤：');
  console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
  console.log('1. 检查 backend/.env 文件确保配置正确');
  console.log('2. 创建 frontend/.env 文件（复制自 frontend/.env.example）');
  console.log('3. 运行 npm run migrate 初始化数据库');
  console.log('4. 运行 npm run create-admin 创建管理员账户');
  console.log('5. 运行 npm run dev 启动开发服务器');
  console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
  
  console.log('⚠️  重要提醒：');
  console.log('• 请妥善保管这些密钥，不要泄露给他人');
  console.log('• ENCRYPTION_KEY 一旦设置不可更改');
  console.log('• 不要将 .env 文件提交到 Git 仓库');
  console.log('• 生产环境部署时请重新生成新的密钥');
  console.log('');
}

// 处理Ctrl+C
process.on('SIGINT', () => {
  console.log('\n\n👋 已取消操作。');
  process.exit(0);
});

